package com.saydc.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.saydc.model.Busqueda;
import com.saydc.model.Empleado;
import com.saydc.model.EstadoBusqueda;
import com.saydc.utils.HibernateUtils;

public class BusquedasDAO {
	
	private static BusquedasDAO instance;

	public static BusquedasDAO getInstance(){
		if(instance == null){
			instance = new BusquedasDAO();
		}
		return instance;
	}
	
	@SuppressWarnings("unchecked")
	public List<Busqueda> getAllBusquedas(){
		Session session = HibernateUtils.currentSession();
    	List<Busqueda> listaBusquedas = (List<Busqueda>)session.createQuery("select b from Busqueda b").list();
    	return listaBusquedas;
    }
	
	@SuppressWarnings("unchecked")
	public List<Busqueda> getBusquedasPendientes(){
    	Session session = HibernateUtils.currentSession();
    	Property idEstado = Property.forName("estado.idEstadoBusqueda");
    	Criteria crit = session.createCriteria(Busqueda.class)
    										.add(Restrictions.disjunction()
    										.add( idEstado.eq(EstadoBusqueda.NUEVA))
    										.add( idEstado.eq(EstadoBusqueda.ACTIVA)));
    	List<Busqueda> listaBusquedasPendientes = crit.list();																
    	return listaBusquedasPendientes;
    }
	
	@SuppressWarnings("unchecked")
	public List<EstadoBusqueda> getAllEstadosBusqueda(){
    	List<EstadoBusqueda> listaEstados= new ArrayList<EstadoBusqueda>();
    	Session session = HibernateUtils.currentSession();
    	listaEstados = session.createQuery("select e from EstadoBusqueda e").list();
    	return listaEstados;
    }
	
	public void altaBusqueda(Busqueda busqueda){
		Session session;
		Transaction tx = null;
		try{
			session = HibernateUtils.currentSession();
			tx = session.beginTransaction();
			session.save(busqueda);
			tx.commit();
		}catch(Exception e){
			tx.rollback();
			e.printStackTrace();
			//TODO throw una exception mia
			System.out.println("Error al insertar en la base");
		}finally{
			HibernateUtils.closeSession();
		}
	}

	public void actualizarBusqueda(Busqueda busqueda) {
		Session session;
		Transaction tx = null;
		try{
			session = HibernateUtils.currentSession();
			tx = session.beginTransaction();
			session.update(busqueda);
			tx.commit();
		}catch(Exception e){
			tx.rollback();
			e.printStackTrace();
			//TODO throw una exception mia
			System.out.println("Error al insertar en la base");
		}finally{
			HibernateUtils.closeSession();
		}
		
	}

	@SuppressWarnings("unchecked")
	public List<Empleado> getEmpleadosCandidatosEspecificoExpertise(Session session, int idPuestoEspecifico, int idExpertise) {
		session = HibernateUtils.currentSession();
		List<Empleado> listaCandidatos = session.createCriteria(Empleado.class)
										.add(Restrictions.eq("puestoActual.idPuesto", idPuestoEspecifico))
										.add(Restrictions.eq("expertise.idExpertise", idExpertise-1))
										.list();
		for(Empleado empleado : listaCandidatos){
			Hibernate.initialize(empleado.getExpertise());
		}
		return listaCandidatos;
	}

	@SuppressWarnings("unchecked")
	public List<Empleado> getEmpleadosCandidatosGenerico(Session session,	int idPuestoEspecifico) {
		session = HibernateUtils.currentSession();
		PuestosDAO dao = PuestosDAO.getInstance();
		int idPuestoGenerico = dao.getPuestoEspecifico(session, idPuestoEspecifico).getIdPuestoGenerico().getIdPuesto();
			
		Criteria criteria = session.createCriteria(Empleado.class);
		criteria.createAlias("puestoActual", "especifico");
		criteria.createAlias("especifico.idPuestoGenerico", "generico");
		criteria.add(Restrictions.eq("generico.idPuesto", idPuestoGenerico));
		
		List<Empleado> listaCandidatos = criteria.list();
		for(Empleado empleado : listaCandidatos){
			Hibernate.initialize(empleado.getExpertise());
		}
		return listaCandidatos;
	}

}
